package com.erpoa.service.impl;

import com.erpoa.annotation.DataBase;
import com.erpoa.constants.DataSourceNames;
import com.erpoa.dto.DealMessage;
import com.erpoa.entity.FMachineCode;
import com.erpoa.entity.PackMessage;
import com.erpoa.mapper.PackServletMapper;
import com.erpoa.service.FactoryUtilService;
import com.erpoa.service.PackServletService;
import com.erpoa.utils.PDAException;
import com.erpoa.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;

/**
 * @author chenjimin
 * @Title: PackServletService
 * @ProjectName oaerp
 * @Description: TODO
 * @date 2021/2/1810:22
 */
@Service
public class PackServletServiceImpl implements PackServletService {
    private static final Logger logger = LoggerFactory.getLogger(PackServletServiceImpl.class);

    @Autowired
    private PackServletMapper packServletMapper;
    @Autowired
    private FactoryUtilService factoryUtilService;


    /**
     * 印刷
     *
     * @param packMessage
     * @param message
     * @param mBarTotalNum
     * @return
     */
    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public boolean functionPrint(PackMessage packMessage, DealMessage message, int mBarTotalNum) {

        boolean check = factoryUtilService.checkUserAndBarcode(packMessage, false);
        if (check) {
            // 机台与条码验证
            HashMap<String, Object> mapResult = checkMachineAndBarCode(packMessage, message);
            if (Boolean.parseBoolean(mapResult.get("chkResult").toString())) {
                System.out.println("机台与条码检验成功");
                // 排程尚欠与状态获取
                String statusAndUnqty = factoryUtilService.checkScheduleUnqtyAndStatus(packMessage);
                String[] str = statusAndUnqty.split("##");
                String status = str[0];
                Integer mUnFinQty = Integer.parseInt(str[1]);
                if (!status.equals("NORMAL")) {
                    System.out.println(status);
                    message.setSuccess(false);
                    message.setMessage(status);
                    return false;
                } else {
                    if (!(factoryUtilService.checkErpEnd(mapResult.get("mLOrderNo").toString()) == 0
                            && "F".equals(mapResult.get("mLWorkShopCode").toString()))) {// 是正常工单
                        // 调用存储过程ChkCanConfirm
                        boolean controlMaterial = callCheckCECanConfirm(packMessage, mapResult);
                        if (!controlMaterial) {// 第一次物料管控失败，不能扫该条码以记录产出
                            System.out.println("第一次物料管控失败，不能扫该条码以记录产出");
                            message.setSuccess(false);
                            message.setMessage("料未发足，请先进行领料");
                            return false;
                        }
                    }
                    // 笔芯厂墨水、硅油超发未流转或退料管控 liujiajie 2018-10-24
                    if ("E".equals(mapResult.get("mLFactoryCode").toString())
                            || "Q".equals(mapResult.get("mLFactoryCode").toString())
                            && "F".equals(mapResult.get("mLWorkShopCode").toString())) {
                        String messages = cartridgeControl(packMessage, mapResult);
                        if ("N".equals(messages.split("##")[0])) {
                            message.setSuccess(false);
                            message.setMessage(messages.split("##")[1]);
                            return false;
                        }
                    } else {
                        // 上下道工序间的管控 2018-10-24 liujiajie
                        String chkCPro = chkCProCanConfirm(packMessage, mapResult);
                        if ("N".equals(chkCPro.split("##")[0])) {
                            message.setSuccess(false);
                            message.setMessage(chkCPro.split("##")[1]);
                            return false;
                        }
                    }
                    System.out.println("第一次物料管控成功");
                    // 是否发料领料管控
                    String checkResultProcess = CheckCProcessCanConfirm(packMessage, mapResult);
                    if ("N".equals(checkResultProcess.split("##")[0])) {
                        message.setSuccess(false);
                        message.setMessage(checkResultProcess.split("##")[1]);
                        return false;
                    }
                    System.out.println("第二道上下道工序管控完成,开始事务提交操作");
                    // 事务提交所有需要的更新操作
                    boolean tran = transcationToUpdate(packMessage, message, false, false, mBarTotalNum, mUnFinQty,
                            mapResult);
                    if (tran) {
                        System.out.println("事务提交成功");
                        message.setSuccess(true);
                        return true;
                    } else {
                        System.out.println("事务提交失败");
                        message.setSuccess(false);
                        // message.setMessage("原因请找transcationToUpdate");
                        return false;
                    }
                }
            } else {
                System.out.println("机台与条码检验失败");
            }
        } else {
            // System.out.println("基本校验-操作工工号与条码有效性校验失败");
            message.setSuccess(false);
            message.setMessage("基本校验-操作工工号与条码有效性校验失败");
        }
        return false;
    }

    /**
     * 装配
     *
     * @param packMessage
     * @param message
     * @param mBarTotalNum
     * @return
     */
    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public boolean functionAssemble(PackMessage packMessage, DealMessage message, int mBarTotalNum) {
        boolean check = factoryUtilService.checkUserAndBarcode(packMessage, false);
        if (check) {
            // 机台与条码验证
            HashMap<String, Object> mapResult = checkMachineAndBarCode(packMessage, message);
            if (Boolean.parseBoolean(mapResult.get("chkResult").toString())) {
                System.out.println("机台与条码检验成功");
                // 排程尚欠与状态获取
                String statusAndUnqty = factoryUtilService.checkScheduleUnqtyAndStatus(packMessage);
                String[] str = statusAndUnqty.split("##");
                String status = str[0];
                Integer mUnFinQty = Integer.parseInt(str[1]);
                if (!status.equals("NORMAL")) {
                    System.out.println(status);
                    message.setSuccess(false);
                    message.setMessage(status);
                    return false;
                } else {
                    // 调用存储过程ChkCanConfirm
                    boolean controlMaterial = callCheckECanConfirm(packMessage, mapResult);
                    if (!controlMaterial) {// 第一次物料管控失败，不能扫该条码以记录产出
                        message.setSuccess(false);
                        message.setMessage("MES物料没有发够，请先进行领料!");
                        return false;
                    }
                    System.out.println("第一次物料管控成功,开始事务提交操作");
                    // 事务提交所有需要的更新操作
                    boolean tran = transcationToUpdate(packMessage, message, false, false, mBarTotalNum, mUnFinQty,
                            mapResult);
                    if (tran) {
                        System.out.println("事务提交成功");
                        message.setSuccess(true);
                        return true;
                    } else {
                        System.out.println("事务提交失败");
                        message.setSuccess(false);
                        // message.setMessage("原因请找transcationToUpdate");
                        return false;
                    }
                }
            } else {
                System.out.println("机台与条码检验失败");
            }
        } else {
            System.out.println("基本校验失败");
            message.setSuccess(false);
            message.setMessage("基本校验失败");
        }
        return false;
    }

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public boolean functionRefillTwo(PackMessage packMessage, DealMessage message, int mBarTotalNum) {
        boolean check = factoryUtilService.checkUserAndBarcode(packMessage, true);
        if (check) {
            // 机台与条码验证
            HashMap<String, Object> mapResult = checkMachineAndBarCode(packMessage, message);
            if (Boolean.parseBoolean(mapResult.get("chkResult").toString())) {
                System.out.println("机台与条码检验成功");
                // 排程尚欠与状态获取
                String statusAndUnqty = factoryUtilService.checkScheduleUnqtyAndStatus(packMessage);
                String[] str = statusAndUnqty.split("##");
                String status = str[0];
                Integer mUnFinQty = Integer.parseInt(str[1]);
                if (!status.equals("NORMAL")) {
                    System.out.println(status);
                    message.setSuccess(false);
                    message.setMessage(status);
                    return false;
                } else {
                    // 调用存储过程ChkCanConfirm
                    boolean controlMaterial = callChk3CanConfirm(packMessage, mapResult);
                    if (!controlMaterial) {// 第一次管控失败，不能扫该条码以记录产出
                        // System.out.println("第一次管控失败，不能扫该条码以记录产出");
                        message.setSuccess(false);
                        message.setMessage("失败，当前产出大于上道工序产出");
                        return false;
                    }
                    System.out.println("第一次管控成功,开始事务提交操作");
                    logger.info("第一次管控成功,开始事务提交操作");
                    // 事务提交所有需要的更新操作
                    boolean tran = transcationToUpdate(packMessage, message, false, false, mBarTotalNum, mUnFinQty,
                            mapResult);
                    if (tran) {
                        message.setSuccess(true);
                        return true;
                    } else {
                        message.setSuccess(false);
                        // message.setMessage("原因请找transcationToUpdate");
                        return false;
                    }
                }
            } else {
                System.out.println("机台与条码检验失败");
                logger.info("机台与条码检验失败");
            }
        } else {
            System.out.println("基本校验失败");
            logger.info("基本校验失败");
            message.setSuccess(false);
            message.setMessage("基本校验失败");
        }
        return false;
    }

    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public boolean functionOps(PackMessage packMessage, DealMessage dealMessage, int mBarTotalNum) {

        HashMap map = new HashMap();
        map.put("pBarcode", "2323");
        map.put("pPlanID", "2332");
        map.put("pChkResult", "");
        try {
            this.packServletMapper.callChkECanConfirm(map);
        } catch (Exception e) {
            e.printStackTrace();

        }
        System.out.println("基本校验失败");
        System.out.println("基本校验失败");
        System.out.println("基本校验失败");
        System.out.println("基本校验失败");
        System.out.println("基本校验失败");
        return false;
    }


    private boolean callChk3CanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult) {
        try {
            HashMap map = new HashMap();
            map.put("pbarcode", packMessage.getBarcode());
            map.put("pplanid", mapResult.get("mLPlanID").toString());
            map.put("pChkNum", Types.FLOAT);
            map.put("pChkResult", Types.VARCHAR);
            this.packServletMapper.callChk3CanConfirm(map);
            Float oweBackMatWeight = map.get("pChkNum") == null ? 0 : (Float) map.get("pChkNum");//
            if (oweBackMatWeight > 0)
                System.out.println("多于上道工序:" + oweBackMatWeight);
            logger.info("多于上道工序:" + oweBackMatWeight);
            String pChkResult = map.get("pChkNum") == null ? "" : (String) map.get("pChkNum");//
            if ("N".equals(pChkResult)) {
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            throw new PDAException("失败，当前产出大于上道工序产出");
        }
    }


    /**
     * 调用存储过程ChkCanconfirm--物料管控之领料管控
     *
     * @param packMessage
     * @return
     */
    private boolean callCheckECanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult) {
        try {
            HashMap map = new HashMap();
            map.put("pBarcode", packMessage.getBarcode());
            map.put("pPlanID", mapResult.get("mLPlanID").toString());
            map.put("pChkResult", "");
            this.packServletMapper.callChkECanConfirm(map);
            String pChkResult = (String) mapResult.get("pChkResult");// 领料管控结果
            if ("N".equals(pChkResult)) {// 发料不足以产出
                System.out.println("，请先进行领料!");
                logger.info("，请先进行领料!");
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            throw new PDAException("MES物料没有发够，请先进行领料!");
        }
    }


    /**
     * 调用存储过程ChkCProCanConfirm--工单前后工序管控(上一道工序未没有报工确认，下一道工序不允许报工确认(避免上道工序漏确认产出))
     * (印刷)
     *
     * @param packMessage
     * @return
     */
    private String CheckCProcessCanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult) {
        String pChkResult = "";
        String resultMsg = "";
        try {
            HashMap map = new HashMap();
            map.put("pBarcode", packMessage.getBarcode());
            map.put("pPlanID", mapResult.get("mLPlanID").toString());
            map.put("pChkResult", "");
            this.packServletMapper.callChkCCanConfirm(map);
            pChkResult = map.get("pChkResult") == null ? "" : (String) map.get("pChkResult");
            System.out.println(pChkResult + "##" + resultMsg);
            logger.info(pChkResult + "##" + resultMsg);
            return pChkResult + "##" + resultMsg;
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            throw new PDAException(pChkResult + "##" + resultMsg);

        }

    }


    /**
     * 上下道工序管控
     *
     * @param packMessage
     * @param mapResult
     * @return
     */
    private String chkCProCanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult) {

        String pChkResult = "";
        String resultMsg = "";

        try {
            HashMap map = new HashMap();
            map.put("pBarcode", packMessage.getBarcode());
            map.put("pPlanID", mapResult.get("mLPlanID").toString());
            map.put("pReturnNMsg", "");
            map.put("pChkResult", "");
            this.packServletMapper.callChkCProCanConfirm(map);
            resultMsg = map.get("pReturnNMsg") == null ? "" : (String) map.get("pReturnNMsg");
            pChkResult = map.get("pChkResult") == null ? "" : (String) map.get("pChkResult");
            System.out.println(pChkResult + "##" + resultMsg);
            logger.info(pChkResult + "##" + resultMsg);
            return pChkResult + "##" + resultMsg;
        } catch (Exception e) {
            // e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            throw new PDAException(pChkResult + "##" + resultMsg);
        }
    }


    /**
     * 2018-10-25 liujiajie 笔芯厂墨水、硅油超发未流转或退料管控
     *
     * @param packMessage
     * @param mapResult
     * @return
     */

    private String cartridgeControl(PackMessage packMessage, HashMap<String, Object> mapResult) {
        boolean flag = false;
        String resultMsg = "";
        String pChkResult = "N";

        try {
            System.out.println("条码：" + packMessage.getBarcode());
            Integer fPlanQty = this.packServletMapper.selectfplanqty(mapResult.get("mLPlanID").toString()); // 排程任务数
            if (StringUtil.isNull(fPlanQty)) {
                throw new PDAException("该条码不存在!");
            } else {
                int fQty = this.packServletMapper.selectProBarByPlanId(mapResult.get("mLPlanID").toString());// 排程已完成数
                HashMap maptemp = this.packServletMapper.selectqtynoByBarCode(packMessage.getBarcode());
                Integer theQty = maptemp.get("FQTY") == null ? 0 : (Integer) maptemp.get("FQTY"); // 本次完成数
                if (theQty <= 0) {
                    throw new PDAException("条码报次或不存在");
                }
                String fOrderNo = maptemp.get("FORDERNO") == null ? "" : (String) maptemp.get("FORDERNO"); // 工单号

                if (fQty + theQty < fPlanQty) {
                    return "Y##" + resultMsg;
                }
                System.out.println("排程任务数=" + fPlanQty + "\t排程已完成数=" + fQty + "\t本次完成数=" + theQty);
                if ((fQty + theQty) > fPlanQty) {
                    throw new PDAException("条码总产出量会超出排程任务数！");
                }

                float count = 0;
                if (StringUtil.isNotEmpty(fOrderNo)) {

                    HashMap sfatemp = this.packServletMapper.selectSfaSqlByfOrderNo(fOrderNo);
                    if (StringUtil.isNotEmpty(sfatemp)) {
                        throw new PDAException("料件有超发，请流转或退料");
                    }
                    String fMatCode = (String) sfatemp.get("SFA03");// 料号 = rs.getString(1);
                    System.out.println(fMatCode);
                    if (StringUtil.isNotEmpty(fMatCode)) {

                        Float temp = this.packServletMapper.sumfrspqtyByMplanid(fMatCode, mapResult.get("mLPlanID").toString());
                        // 实发-应发>0.1就超发 需要处理
                        System.out.println(temp + "\t" + fPlanQty * (Float) sfatemp.get("SFA161"));
                        count = temp - (fPlanQty * (Float) sfatemp.get("SFA161"));

                    }
                    if (count > 0.1) {
                        throw new PDAException(fMatCode + "料件有超发，请流转或退料");
                    }
                } else {
                    throw new PDAException("工单号为空请处理！");
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            resultMsg = e.getMessage();
            throw new PDAException(pChkResult + "##" + resultMsg);
        }
        // return pChkResult + "##" + resultMsg;
        return "Y##" + resultMsg;
    }


    /**
     * 调用存储过程ChkCanconfirm--物料管控之领料管控(印刷)
     *
     * @param packMessage
     * @return
     */
    private boolean callCheckCECanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult) {
        try {

            HashMap map = new HashMap();
            map.put("pBarcode", packMessage.getBarcode());
            map.put("pPlanID", mapResult.get("mLPlanID").toString());
            map.put("pChkResult", "");
            this.packServletMapper.callChkCCanConfirm(map);

            String pChkResult = map.get("pChkResult") == null ? "" : map.get("pChkResult").toString();// 领料管控结果
            if ("N".equals(pChkResult)) {// 发料不足以产出
                System.out.println("料未发足，请先进行领料!");
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            throw new PDAException("料未发足，请先进行领料");
        }
    }


    /**
     * 功能注塑
     *
     * @param packMessage
     * @param message
     * @param mBarTotalNum
     * @return
     */
    @Override
    @DataBase(DataSourceNames.DSX5)
    @Transactional()
    public boolean functionPlastic(PackMessage packMessage, DealMessage message, int mBarTotalNum) {
        boolean check = factoryUtilService.checkUserAndBarcode(packMessage, false);
        if (check) {
            // 机台与条码验证
            HashMap<String, Object> mapResult = checkMachineAndBarCode(packMessage, message);
            if (Boolean.parseBoolean(mapResult.get("chkResult").toString())) {
                // System.out.println("机台与条码检验成功");
                // 排程尚欠与状态获取
                String statusAndUnqty = factoryUtilService.checkScheduleUnqtyAndStatus(packMessage);
                String[] str = statusAndUnqty.split("##");
                String status = str[0];
                Integer mUnFinQty = Integer.parseInt(str[1]);
                if (!status.equals("NORMAL")) {
                    // System.out.println(status);
                    message.setSuccess(false);
                    message.setMessage(status);
                    return false;
                } else {
                    // 正常工单物料管控,注塑返工工单不需要物料管控
                    if (factoryUtilService.isNormalOrder(packMessage.getBarcode())) {// 是正常工单
                        // 调用存储过程ChkCanConfirm
                        boolean controlMaterial = callChkCanConfirm(packMessage, mapResult, mBarTotalNum, mUnFinQty);
                        if (!controlMaterial) {// 第一次物料管控失败，不能扫该条码以记录产出
                            // System.out.println("第一次物料管控失败，不能扫该条码以记录产出");
                            //TODO CJM
                            message.setSuccess(false);
                            message.setMessage("料未发足，请先进行领料");
                            return false;
                        }
                    }
                    // System.out.println("第一次物料管控成功,开始事务提交操作");
                    // 事务提交所有需要的更新操作
                    boolean tran = transcationToUpdate(packMessage, message, false, true, mBarTotalNum, mUnFinQty,
                            mapResult);
                    if (tran) {
                        // System.out.println("事务提交成功");
                        message.setSuccess(true);
                        return true;
                    } else {
                        // System.out.println("事务提交失败");
                        message.setSuccess(false);
                        // message.setMessage("原因请找transcationToUpdate");
                        return false;
                    }
                }
            } else {
                // System.out.println("机台与条码检验失败");
            }
        } else {
            // System.out.println("基本校验-操作工工号与条码有效性校验失败");
            message.setSuccess(false);
            message.setMessage("基本校验-操作工工号与条码有效性校验失败");
        }
        return false;
    }


    /**
     * 开启事务提交对数据库的更新
     *
     * @param packMessage
     * @throws PDAException
     */
    private boolean transcationToUpdate(PackMessage packMessage, DealMessage message, boolean isTwo,
                                        boolean endMatControl, int mBarTotalNum, int mUnFinQty, HashMap<String, Object> mapResult) throws PDAException {
        if (isTwo) {
            updateTableMG_ProcessBarCode_FirstForTwo(packMessage);
        } else {
            //TODO CJM 更新条码表
            updateTableMG_ProcessBarCode_First(packMessage);
        }
        // 更新排程表
        updateTableMG_OrderPlan_First(packMessage, mapResult.get("mLPlanID").toString());
        // 物料管控-最后一张标签执行退料管控
        if (endMatControl && !isTwo) {
            if (mUnFinQty == mBarTotalNum && factoryUtilService.isNormalOrder(packMessage.getBarcode())) {
                // 调用存储过程ChkEndCanConfirm
                boolean controlMaterial = callChkEndCanConfirm(packMessage, mapResult, mBarTotalNum, mUnFinQty);
                if (!controlMaterial) {// 第二次物料管控失败，不能扫该条码以记录产出
                    // System.out.println("第二次物料管控失败，即将进行事务回滚");
                    // message.setSuccess(false);
                    // message.setMessage("第二次物料管控失败-退料管控");
                    throw new PDAException("物料管控————超领，请先退料");
                }
            }
        }
        // 更新排程表[完成数fFinshQty],[未完成数funfinQty],[状态forderstatus],[实际完成日期ffinishdate]
        updateTableMG_OrderPlan_Second(packMessage, mBarTotalNum, mapResult.get("mLPlanID").toString());
        // 更新条码表[已确认fConfirm],[产出扫描人fConfirmScaner],[完成时间fFinishDate]
        updateTableMG_ProcessBarCode_Second(packMessage);

        return true;


    }


    /**
     * 第二次更新条码表[已确认fConfirm],[产出扫描人fConfirmScaner],[完成时间fFinishDate]
     *
     * @param packMessage
     * @throws Exception
     */
    private void updateTableMG_ProcessBarCode_Second(PackMessage packMessage) throws PDAException {

        int updateNum = this.packServletMapper.updateprocessByParamsecond(packMessage.getUser().getsCode(), packMessage.getBarcode(),
                packMessage.getMachine());
        if (updateNum <= 0) {
            throw new PDAException(String.format("第二次更新条码表失败"));
        }
    }

    /**
     * 第2次去更新排程表
     * [完成数fFinshQty],[未完成数funfinQty],[状态forderstatus],[实际完成日期ffinishdate]
     *
     * @param packMessage
     * @throws Exception
     */
    private void updateTableMG_OrderPlan_Second(PackMessage packMessage, int mBarTotalNum,
                                                String mLPlanID) throws PDAException {
        // [完成数fFinshQty],[未完成数funfinQty],[状态forderstatus],[实际完成日期ffinishdate]
        // 0 0 0 0 1
        int fqty = this.packServletMapper.selectsumfqtysecond(packMessage.getBarcode()); // 当前完成数
        int lqty = mBarTotalNum;
        logger.info(packMessage.getTime() + "第二次更新排程表^" + ";参数(" + packMessage.getBarcode() + ")");
        int updateNum = this.packServletMapper.updateorplanByParamsecond(fqty, lqty, mLPlanID);
        if (updateNum <= 0) {
            throw new PDAException("第二次更新排程表完成数出现异常");
        }
    }


    /**
     * 调用存储过程ChkEndCanConfirm--物料管控之退料管控
     *
     * @param packMessage
     * @param mapResult
     * @param mBarTotalNum
     * @param mUnFinQty
     * @return
     */
    private boolean callChkEndCanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult, int mBarTotalNum, int mUnFinQty) {
        try {
            HashMap map = new HashMap();
            map.put("pBarcode", packMessage.getBarcode());
            map.put("pPlanID", mapResult.get("mLPlanID").toString());
            map.put("pOweBackMatWeight", 0);
            map.put("pChkResult", "");
            this.packServletMapper.callChkEndCanConfirm(map);
            Float oweBackMatWeight = map.get("pOweBackMatWeight") == null ? 0 : (Float) map.get("pOweBackMatWeight");// 欠料量，欠料数量小于等于0，料已发足

            String pChkResult = map.get("pChkResult") == null ? "" : (String) map.get("pChkResult");// 领料管控结果
            if ("N".equals(pChkResult)) {// 需要先退料，再进行产出记录
                // 记录异常产出状态并写入数据库
                int update = this.packServletMapper.insertOutControlBuParam(UUID.randomUUID().toString(), packMessage.getMachine(),
                        mapResult.get("mLOrderNo").toString(), packMessage.getBarcode(), packMessage.getJobnum(),
                        ((mUnFinQty == mBarTotalNum) ? "Y" : "N"), packMessage.getUser().getsCode(),
                        mapResult.get("mLFactoryCode").toString(), mapResult.get("mLWorkShopCode").toString(), (oweBackMatWeight * -1f));
                System.out.println("记录异常产出状态" + update + "条");
                System.out.println("物料管控————超领：" + (oweBackMatWeight + 0.01f) + " KG!请至少退回" + oweBackMatWeight + "KG!");
                // throw new Exception("物料管控————超领：" + (oweBackMatWeight + 0.01)
                // + " KG!请至少退回" + oweBackMatWeight + "KG!");
                return false;
            } else {
                return true;
            }
        } catch (
                Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            throw new PDAException("物料管控————超领，请先退料");
        }

    }


    /**
     * 第一次去更新排程表 [实际开始时间fStartDate] 只有第一次会去更新实际开始时间，也就是UpdateNum可能=0
     *
     * @param packMessage
     * @throws Exception
     */
    private void updateTableMG_OrderPlan_First(PackMessage packMessage, String mLPlanID) throws PDAException {


        logger.info(
                packMessage.getTime() + "第一次更新排程表^" + ";参数(" + packMessage.getBarcode() + ")：" + mLPlanID);

        int updateNum = this.packServletMapper.updateorderplanByPlanId(mLPlanID);

        if (updateNum <= 0) {
            // throw new Exception("第一次更新排程表实际开始时间出现异常");
        }
    }

    /**
     * 第一次更新条码表[操作工fOperatorCode]
     *
     * @param packMessage
     * @throws Exception
     */
    private void updateTableMG_ProcessBarCode_First(PackMessage packMessage) throws PDAException {

        logger.info(packMessage.getTime() + "第一次更新条码表^" + ";参数：" + packMessage.getJobnum() + " "
                + packMessage.getBarcode() + " " + packMessage.getMachine());
        System.out.println(packMessage.getTime() + "第一次更新条码表^" + ";参数：" + packMessage.getJobnum() + " "
                + packMessage.getBarcode() + " " + packMessage.getMachine());

        int updateNum = this.packServletMapper.updateProcessBarByparamfirst(packMessage.getJobnum(), packMessage.getBarcode(), packMessage.getMachine());

        if (updateNum <= 0) {
            throw new PDAException(
                    String.format("机台或班组%s不存在该条码%s或该条码已被确认!", packMessage.getMachine(), packMessage.getBarcode()));
        }
    }

    private void updateTableMG_ProcessBarCode_FirstForTwo(PackMessage mes) throws PDAException {

        List<String> jobnums = this.packServletMapper.selectmembByMachJobnum(mes.getMachine(), mes.getJobnum());
        if (StringUtil.isEmpty(jobnums)) {
            throw new PDAException(String.format("未查询到任何班组!", mes.getMachine(), mes.getBarcode()));
        }
        System.out.println(jobnums.size());
        Integer total = this.packServletMapper.selectFqtyBybarCode(mes.getBarcode());
        int avg = total / jobnums.size();
        int last = total - avg * (jobnums.size());
        last += avg;
        for (int i = 0; i < jobnums.size() - 1; i++) {
            int updateNum = this.packServletMapper.insertProcessByParam(UUID.randomUUID().toString(), avg, mes.getBarcode(),
                    mes.getMachine(), mes.getUser().getsCode(), jobnums.get(i));
            if (updateNum <= 0) {
                throw new PDAException(String.format("1机台或班组%s不存在该条码%s!", mes.getMachine(), mes.getBarcode()));
            }
        }
        int updateNum = this.packServletMapper.updateProcessByParam(jobnums.get(jobnums.size() - 1), mes.getBarcode(), mes.getMachine(), last);
        if (updateNum <= 0) {
            throw new PDAException(String.format("2机台或班组%s不存在该条码%s或该条码已被确认!", mes.getMachine(), mes.getBarcode()));
        }
    }


    /**
     * 调用存储过程ChkCanconfirm--物料管控之领料管控
     *
     * @param packMessage
     * @return
     */
    private boolean callChkCanConfirm(PackMessage packMessage, HashMap<String, Object> mapResult, int mBarTotalNum,
                                      int mUnFinQty) {
        try {
            HashMap hashMap = new HashMap();
            hashMap.put("pBarcode", packMessage.getBarcode());
            hashMap.put("pPlanID", mapResult.get("mLPlanID").toString());
            hashMap.put("pOweMatWeight", 0);
            hashMap.put("pChkResult", 0);
            this.packServletMapper.callChkCanConfirm(hashMap);
            float oweMatWeight = hashMap.get("pOweMatWeight") == null ? 0 : (Float) hashMap.get("pOweMatWeight");// 欠料量，欠料数量小于等于0，料已发足
            String pChkResult = hashMap.get("pChkResult") == null ? "" : (String) hashMap.get("pChkResult");// 领料管控结果
            if ("N".equals(pChkResult)) {// 发料不足以产出
                // 记录异常产出状态并写入数据库
                String recordSQL = "insert into outControlRecords("
                        + "fid,version,fmachinecode,forderno,fbarcode,FOPERATORCODE,fdifference,fendbarcode,"
                        + "FCREATEPER,FCREATEDATE,ffactorycode,fworkshopcode) " + "values('%s',0,'%s','%s','%s','%s',"
                        + oweMatWeight + ",'%s','%s',sysdate,'%s','%s')";
                int update = this.packServletMapper.finsertoutcrs(UUID.randomUUID().toString(), packMessage.getMachine(),
                        mapResult.get("mLOrderNo").toString(), packMessage.getBarcode(), packMessage.getJobnum(),
                        ((mUnFinQty == mBarTotalNum) ? "Y" : "N"), packMessage.getUser().getsCode(),
                        oweMatWeight, mapResult.get("mLFactoryCode").toString(), mapResult.get("mLWorkShopCode").toString());
                System.out.println("记录异常产出状态" + update + "条");
                logger.info("记录异常产出状态" + update + "条");
                logger.info("物料管控————料未发足，请先进行领料！还有" + oweMatWeight + "料没有领");
                System.out.println("物料管控————料未发足，请先进行领料！还有" + oweMatWeight + "料没有领");
                // throw new Exception("物料管控————料未发足，请先进行领料！还有" + oweMatWeight +
                // "料没有领");
                return false;
            } else {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());

            throw new PDAException("料未发足，请先进行领料");
        }
    }


    /**
     * 校验机台号和条码是否匹配
     *
     * @param packMessage
     * @return
     */
    private HashMap<String, Object> checkMachineAndBarCode(PackMessage packMessage, DealMessage message) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        try {
            FMachineCode tempvailds = this.packServletMapper.checkMachineAndBarCodevaild(packMessage.getBarcode());
            if (StringUtil.isNull(tempvailds)) {
                throw new PDAException("没有找到数据");
            }
            if ((packMessage.getMachine().toLowerCase()).equals(tempvailds.getFMachineCode().toLowerCase())) {// 机台码符合
                if (tempvailds.getFConfirm() != 1) {// 条码没有被确认
                    map.put("mLPlanID", tempvailds.getFPlanID());
                    map.put("mLOrderNo", tempvailds.getForderno());
                    map.put("mLFactoryCode", tempvailds.getFfactorycode());
                    map.put("mLWorkShopCode", tempvailds.getFworkshopcode());
                    map.put("chkResult", true);
                    return map;
                } else {// 条码已经被确认
                    System.out.println("机台与条码检验失败-条码已经被确认");
                    message.setSuccess(false);
                    message.setMessage("机台与条码检验失败-条码已经被确认");

                    map.put("chkResult", false);
                    return map;
                }
            } else {// 机台码不符合
                System.out.println("机台与条码检验失败-机台码不符合");
                message.setSuccess(false);
                message.setMessage("机台与条码检验失败-机台码不符合");
                map.put("chkResult", false);
                return map;
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            logger.info(e.getMessage());
            map.put("chkResult", false);
            return map;
        }
    }
}
